
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32; // 大小为四字节共32位

#define PERIPE_BASE ((u32)0x40000000)				// 片上外设基地址
#define APB2PERIPH_BASE (PERIPE_BASE + 0x00010000) // 总线基地址，GPIO都挂载在APB2上

// APB2和APB1挂载在总线上
#define RCCPERIPH_BASE (PERIPE_BASE + 0x21000) // 端口时钟基地址

// 端口时钟GPIO基地址
#define RCCGPIO_BASE (RCCPERIPH_BASE + 0x18) // 0x400221018

// GPIO_A外设基地址
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) // 0x4001 0800
// GPIO_B外设基地址
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
// GPIO_C外设基地址
#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)

// int char short float double
typedef struct
{
	u32 CR;		  // 偏移地址0x00
	u32 CFGR;	  // 偏移地址0x04
	u32 CIR;	  // 偏移地址0x08
	u32 APB2RSTR; // 偏移地址0x0C
	u32 APB1RSTR; // 偏移地址0x10
	u32 AHBENR;	  // 偏移地址0x14
	u32 APB2ENR;  // 偏移地址0x18
	u32 APB1ENR;  // 偏移地址0x1C
	u32 BDCR;	  // 偏移地址0x20
	u32 CSR;	  // 偏移地址0x24
} RCC_TypeDef;
// 结构体类型
typedef struct
{
	u32 CRL;  // GPIO 端口配置低寄存器		地址偏移 0x00
	u32 CRH;  // GPIO 端口配置高寄存器		地址偏移 0x04
	u32 IDR;  // GPIO 数据输入寄存器		地址偏移 0x08
	u32 ODR;  // GPIO 数据输出寄存器		地址偏移 0x0C
	u32 BSRR; // GPIO 位设置/清除寄存器		地址偏移 0x10
	u32 BRR;  // GPIO 端口位清除寄存器		地址偏移 0x14
	u32 LCKR; // GPIO 端口配置锁定寄存器	地址偏移 0x18
} GPIO_TypeDef;

typedef enum
{
	GPIO_Mode_CLEAR = 0xf,		  // 清空
	GPIO_Mode_AIN = 0x00,		  // 模拟输入
	GPIO_Mode_IN_FLOATING = 0x04, // 浮空输入
	GPIO_Mode_IPD = 0x08,		  // 上拉/下拉输入
	//	GPIO_Mode_IPU = 0x08,          //上拉输入
	// 输出频率为10Mhz
	GPIO_Mode_Out_PP = 0x01, // 推挽输出
	GPIO_Mode_Out_OD = 0x05, // 开漏输出
	GPIO_Mode_AF_OD = 0x09,	 // 复合开漏输出
	GPIO_Mode_AF_PP = 0x0D	 // 复合推挽输出
} GPIOMode_TypeDef;

// 延时函数
void delay(volatile u32 n);

int main()
{
	int i = 0;
	GPIO_TypeDef *GPIO_B;
	GPIO_B = (GPIO_TypeDef *)GPIOB_BASE;
	GPIO_B->CRL |= ~0xf;

	*(u32 *)RCCGPIO_BASE |= 1 << 3;
	(GPIO_B->CRL) &= ~(GPIO_Mode_CLEAR << 0);
	(GPIO_B->CRL) |= (GPIO_Mode_Out_PP << 0);

	while (1)
	{
		for (i = 0; i < 1000; i++)
		{
			(GPIO_B->ODR) &= ~(1 << 0);
			delay(i);
			(GPIO_B->ODR) |= (1 << 0);
			delay(100 - i);
		}
	}
}
// 延时函数
void delay(volatile u32 n)
{
	while (n--)
		;
}

void SystemInit(void)
{
}
